package com.topisv.tms.service.lpn;

import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.hibernate.ejb.criteria.predicate.ComparisonPredicate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.topisv.tms.entity.lpn.LPN;
import com.topisv.tms.repository.lpn.LPNDao;
import com.topisv.tms.service.account.ShiroDbRealm.ShiroUser;
import com.topisv.tms.service.base.BaseService;

@Component
@Transactional(readOnly = true)
public class LPNService  extends BaseService {
	protected Logger logger = LoggerFactory.getLogger(getClass());
	@Autowired
	private LPNDao lpnDao;
	/**
	 * 分页查询
	 * 
	 * @param param
	 * @return
	 */
	public Page<LPN> loadPageByParam(Map<String, Object> param,
			int pageNumber, int pageSize) {
		try{
			PageRequest pageRequest = new PageRequest(pageNumber - 1, pageSize,new Sort(Direction.DESC,"id"));
			Specification<LPN> spec = this.getWhereClause(param);

			Page<LPN> page = this.lpnDao.findAll(spec,
					pageRequest);
			return page;
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
		
	}
	/**
	 * 查询条件封装
	 * @param param
	 * @return
	 */
	private Specification<LPN> getWhereClause(
			final Map<String, Object> param) {

		return new Specification<LPN>() {

			@Override
			public Predicate toPredicate(Root<LPN> r,
					CriteriaQuery<?> q, CriteriaBuilder cb) {
				Predicate pre = cb.conjunction();
				ShiroUser curUser = (ShiroUser) SecurityUtils.getSubject()
						.getPrincipal();

				try {

					

					String warehouseCode = (String) param.get("warehouseCode");
					if (StringUtils.isNotEmpty(warehouseCode)) {
						pre.getExpressions().add(
								cb.equal(r.<String> get("warehouseCode"),
										warehouseCode));
					} else {
						String areagroups = curUser.areagroups;
						if (StringUtils.isNotBlank(areagroups)) {
							String[] areagroupSplit = areagroups.split(":");
							ComparisonPredicate[] areagroupArray = new ComparisonPredicate[areagroupSplit.length];
							int j = 0;
							for (String _areagroup : areagroupSplit) {
								areagroupArray[j] = (ComparisonPredicate) cb
										.equal(r.get("warehouseCode"),
												_areagroup);
								j++;
							}
							pre.getExpressions().add(cb.or(areagroupArray));
						}
						
					}
					String lpnNo = (String) param.get("lpnNo");
					if (StringUtils.isNotEmpty(lpnNo)) {
						pre.getExpressions().add(
								cb.equal(r.get("lpnNo"), lpnNo));
					}
					String type = (String) param.get("type");
					if (StringUtils.isNotEmpty(type)) {
						pre.getExpressions().add(
								cb.equal(r.get("storageType"), type));
						
					}
					String status = (String) param.get("status");
					if (StringUtils.isNotEmpty(status)) {
						pre.getExpressions().add(
								cb.equal(r.get("status"), status));
					}else{
						pre.getExpressions().add(
								cb.notEqual(r.get("status"), "2"));
					}
					pre.getExpressions().add(
							cb.notEqual(r.get("storageType"), 2));
				} catch (Exception e) {
				}

				return pre;
			}
		};
	}
	
    @Transactional(readOnly = false)
    public LPN save(LPN lpn) {
        return lpnDao.save(lpn);
    }
    
	public LPN findLPNById(Long id) throws Exception {
		try {
			return lpnDao.findOne(id);
		} catch (Exception e) {
			throw e;
		}
	}
	@Transactional(readOnly = false)
	public void deleteLPN(LPN lpn) throws Exception {
		try {
			lpn.setLastModifyTime(new Date());
			lpn.setStatus("2");
			this.lpnDao.save(lpn);
		} catch (Exception e) {
			throw e;
		}
	}
	public List<LPN> checkLPN(String warehouseCode,String lpnNo) throws Exception {
		try {
			return lpnDao.checkLPN(warehouseCode,lpnNo);
		} catch (Exception e) {
			throw e;
		}
	}
	
}
